home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / comm2 / kms20src.lha / KMSC / ums2kms.c < prev    next >
C/C++ Source or Header  |  1994-09-16  |  28KB  |  1,020 lines

  1. /**
  2.  **     UMS2KMS.c
  3.  **
  4.  **     Creates KMS area tree from UMS message base groups.
  5.  **
  6.  **     © Copyright 1994 Thomas Schwarz, Germany
  7.  **                      All Rights Reserved.
  8.  **/
  9.  
  10. // Includes
  11.  
  12. #include <KMS/KMS.h>
  13. #include <KMS/KMS_devlib.h>
  14.  
  15. // Defines
  16.  
  17. // Prototypes
  18.  
  19. UWORD MyBreak(VOID);
  20. VOID main(UWORD, STRPTR *);
  21. VOID Cleanup(VOID);
  22. BOOL ParseArgs(VOID);
  23. BOOL ReadAreaList(VOID);
  24. BOOL WriteAreaList(VOID);
  25. struct AreaNode *GroupSearch(STRPTR name);
  26. struct AreaNode *AreaSearch(STRPTR name);
  27. VOID CreatePath(struct AreaNode *area);
  28. struct AreaNode *SetArea(UWORD idx);
  29. struct AreaNode *InsertArea(VOID);
  30. VOID Upper(STRPTR string);
  31. VOID Lower(STRPTR string);
  32. VOID ConvertSpaces(STRPTR string);
  33. VOID LinkArea(struct AreaNode *mother, struct AreaNode *newan);
  34.  
  35. // Global vars
  36.  
  37. STRPTR Version = "\0$VER: UMS2KMS 1.0 ("__COMMODORE_DATE__")";
  38.  
  39. struct MinList AreaList;
  40. STRPTR AreaFile = NULL;
  41. STRPTR KMSRoot = NULL;
  42. STRPTR Pattern = NULL;
  43. STRPTR DOSPatt = NULL;
  44. BOOL Force;
  45. TEXT PathString[LEN_KMSPATH+1];
  46.  
  47. /*********************************
  48.  * MyBreak                       *
  49.  *********************************
  50.  * I: ---                        *
  51.  * O: 0                          *
  52.  *********************************/
  53.  
  54. /// MyBreak
  55.  
  56. UWORD MyBreak(VOID)
  57.    {
  58.    return 0;
  59.    }
  60.  
  61. ///
  62.  
  63. /*********************************
  64.  * main                          *
  65.  *********************************
  66.  * I: argc, argv                 *
  67.  * O: ---                        *
  68.  *********************************/
  69.  
  70. /// main
  71.  
  72. VOID main(UWORD argc, STRPTR *argv)
  73.    {
  74.    UMSAccount *account;
  75.  
  76.    onbreak(MyBreak);
  77.  
  78.    NewList((struct List *)&AreaList);
  79.  
  80.    if (!ParseArgs())
  81.       exit(20);
  82.  
  83.    if (!ReadAreaList())
  84.       {
  85.       Cleanup();
  86.       exit(20);
  87.       }
  88.  
  89.    if (Pattern)
  90.       {
  91.       DOSPatt = malloc(strlen(Pattern) * 2 + 2);
  92.       if (DOSPatt)
  93.          ParsePatternNoCase(Pattern, DOSPatt, strlen(Pattern) * 2 + 2);
  94.       else
  95.          {
  96.          fprintf(stderr, "Error: out of memory!\n");
  97.          Cleanup();
  98.          exit(20);
  99.          }
  100.       }
  101.  
  102.    /* System-Login */
  103.  
  104.    TEXT varbuff[32] = "";
  105.    TEXT pwbuff[32] = "";
  106.    GetVar("KMSMB", varbuff, sizeof(varbuff), NULL);
  107.    GetVar("KMSPWD", pwbuff, sizeof(pwbuff), NULL);
  108.    if (!(account = UMSRLogin(varbuff, "KMS", pwbuff)))
  109.       {
  110.       fprintf(stderr, "Error: couldn't log into UMS!\n");
  111.       Cleanup();
  112.       exit(20);
  113.       }
  114.  
  115.    STRPTR group, group2, arg; /* Pointer to group name */
  116.    struct AreaNode *apoint, *newapoint, *mother, *root;
  117.  
  118.    /* First create KMS root if not exists */
  119.  
  120.    root = SetArea(1);
  121.    if (!root)
  122.       {
  123.       root = InsertArea();
  124.       if (!root)
  125.          {
  126.          fprintf(stderr, "Error: couldn't create KMS root area!\n");
  127.          Cleanup();
  128.          UMSLogout(account);
  129.          exit(20);
  130.          }
  131.  
  132.       strcpy(root->AreaData.Name, "PRIVAT");
  133.       strcpy(root->AreaData.Info, "- Private Mail -");
  134.       strcpy(root->AreaData.MBName, "");
  135.       strcpy(root->AreaData.FilePath, "KMS:Files/");
  136.       root->AreaData.Type = ATYPE_PRIVATE;
  137.       root->AreaData.ReadLevel = 1;
  138.       root->AreaData.WriteLevel = 1;
  139.       root->AreaData.EditLevel = 255;
  140.       root->AreaData.QuoteStr = 1;
  141.       root->AreaData.PQuoteStr = 1;
  142.       root->AreaData.ResendStr = 1;
  143.       root->AreaData.ForwardStr = 1;
  144.       root->AreaData.OriginStr = 1;
  145.       root->AreaData.HoldNum = 0;
  146.       root->AreaData.HoldDays = 0;
  147.       root->AreaData.Mother = 0;
  148.       root->AreaData.Daughter = 0;
  149.       root->AreaData.Next = 0;
  150.       }
  151.  
  152.    /* Main root ok, now create given root for area tree */
  153.  
  154.    if (KMSRoot)
  155.       {
  156.       ConvertSpaces(KMSRoot);
  157.       
  158.       apoint = AreaSearch(KMSRoot);
  159.       if (!apoint)
  160.          {
  161.          newapoint = InsertArea();
  162.          if (!newapoint)
  163.             {
  164.             fprintf(stderr, "Error: couldn't create given root area!\n");
  165.             Cleanup();
  166.             UMSLogout(account);
  167.             exit(20);
  168.             }
  169.  
  170.          strncpy(newapoint->AreaData.Name, KMSRoot, sizeof(newapoint->AreaData.Name)-1);
  171.          newapoint->AreaData.Name[sizeof(newapoint->AreaData.Name)-1] = '\0';
  172.          Upper(newapoint->AreaData.Name);
  173.          strncpy(newapoint->AreaData.Info, KMSRoot, sizeof(newapoint->AreaData.Info)-1);
  174.          newapoint->AreaData.Info[sizeof(newapoint->AreaData.Info)-1] = '\0';
  175.          strncpy(newapoint->AreaData.MBName, KMSRoot, sizeof(newapoint->AreaData.MBName)-1);
  176.          newapoint->AreaData.MBName[sizeof(newapoint->AreaData.MBName)-1] = '\0';
  177.          Lower(newapoint->AreaData.MBName);
  178.          strcpy(newapoint->AreaData.FilePath, "");
  179.          newapoint->AreaData.Type = ATYPE_NEWS;
  180.          newapoint->AreaData.ReadLevel = 0;
  181.          newapoint->AreaData.WriteLevel = 0;
  182.          newapoint->AreaData.EditLevel = 255;
  183.          newapoint->AreaData.QuoteStr = 1;
  184.          newapoint->AreaData.PQuoteStr = 1;
  185.          newapoint->AreaData.ResendStr = 1;
  186.          newapoint->AreaData.ForwardStr = 1;
  187.          newapoint->AreaData.OriginStr = 1;
  188.          newapoint->AreaData.HoldNum = 0;
  189.          newapoint->AreaData.HoldDays = 0;
  190.  
  191.          LinkArea(root, newapoint);
  192.  
  193.          root = newapoint;
  194.          }
  195.       else
  196.          root = apoint;
  197.       }
  198.  
  199.    /* First group: all private messages */
  200.    
  201.    if (group=strdup("")) 
  202.       {
  203.       UMSMsgNum num=0;
  204.  
  205.       /* Print header */
  206.       
  207.       printf("\nWell, let's do the twist :-) ...\n\n");
  208.  
  209.       /* Set local bit 0 in all messages with NO ViewAccess */
  210.  
  211.       UMSSelectTags(account,UMSTAG_SelWriteLocal, TRUE,
  212.                             UMSTAG_SelSet,        1,
  213.                             UMSTAG_SelMask,       UMSUSTATF_ViewAccess,
  214.                             UMSTAG_SelMatch,      0,
  215.                             TAG_DONE);
  216.  
  217.       /* For all groups */
  218.       
  219.       for (;;) 
  220.          {
  221.          /* Do the work */
  222.  
  223.          /* Set local bit 0 on all messages in message group */
  224.          
  225.          UMSSelectTags(account,UMSTAG_SelWriteLocal, TRUE,
  226.                                UMSTAG_SelSet,        1,
  227.                                UMSTAG_SelQuick,      TRUE,
  228.                                UMSTAG_WGroup,        group,
  229.                                TAG_DONE);
  230.  
  231.          if (strlen(group) && (!Pattern || MatchPatternNoCase(DOSPatt, group)))
  232.             {
  233.             /* Print group name */
  234.             
  235.             printf("UMS Group: \"%s\"\n", group);
  236.  
  237.             group2 = strdup(group);
  238.             if (!group2)
  239.                {
  240.                fprintf(stderr, "Error: out of memory!\n");
  241.                free(group);
  242.                break;
  243.                }
  244.  
  245.             apoint = GroupSearch(group);
  246.             if (!apoint || Force)
  247.                {
  248.                /* No corresponding KMS area found -> create one */
  249.  
  250.                newapoint = NULL;
  251.                *group2 = '\0';
  252.                mother = root;
  253.  
  254.                for (arg = strtok(group, "."); arg; arg = strtok(NULL, "."))
  255.                   {
  256.                   if (strlen(group2))
  257.                      strcat(group2, ".");
  258.                   strcat(group2, arg);
  259.  
  260.                   apoint = GroupSearch(group2);
  261.                   if (!apoint)
  262.                      {
  263.                      /* Create next KMS area under current mother */
  264.  
  265.                      newapoint = InsertArea();
  266.                      if (!newapoint)
  267.                         {
  268.                         fprintf(stderr, "Error: couldn't create new area!\n");
  269.                         free(group);
  270.                         free(group2);
  271.                         break;
  272.                         }
  273.  
  274.                      strncpy(newapoint->AreaData.Name, arg, sizeof(newapoint->AreaData.Name)-1);
  275.                      newapoint->AreaData.Name[sizeof(newapoint->AreaData.Name)-1] = '\0';
  276.                      Upper(newapoint->AreaData.Name);
  277.                      ConvertSpaces(newapoint->AreaData.Name);
  278.                      strncpy(newapoint->AreaData.Info, group2, sizeof(newapoint->AreaData.Info)-1);
  279.                      newapoint->AreaData.Info[sizeof(newapoint->AreaData.Info)-1] = '\0';
  280.                      strncpy(newapoint->AreaData.MBName, group2, sizeof(newapoint->AreaData.MBName)-1);
  281.                      newapoint->AreaData.MBName[sizeof(newapoint->AreaData.MBName)-1] = '\0';
  282.                      strcpy(newapoint->AreaData.FilePath, "");
  283.                      newapoint->AreaData.Type = ATYPE_NEWS;
  284.                      newapoint->AreaData.ReadLevel = 0;
  285.                      newapoint->AreaData.WriteLevel = 0;
  286.                      newapoint->AreaData.EditLevel = 255;
  287.                      newapoint->AreaData.QuoteStr = 1;
  288.                      newapoint->AreaData.PQuoteStr = 1;
  289.                      newapoint->AreaData.ResendStr = 1;
  290.                      newapoint->AreaData.ForwardStr = 1;
  291.                      newapoint->AreaData.OriginStr = 1;
  292.                      newapoint->AreaData.HoldNum = 0;
  293.                      newapoint->AreaData.HoldDays = 0;
  294.                      
  295.                      LinkArea(mother, newapoint);
  296.  
  297.                      printf("         ! \"%s\" created\n", group2);
  298.                      
  299.                      mother = newapoint; /* update mother */
  300.                      }
  301.                   else
  302.                      {
  303.                      printf("         - \"%s\" exists\n", group2);
  304.  
  305.                      mother = apoint; /* update mother */
  306.                      }
  307.                   }
  308.                
  309.                CreatePath(mother);
  310.                if (newapoint)
  311.                   printf("=> KMS =>: %s\n", PathString);
  312.                else
  313.                   printf("-> KMS ->: %s\n", PathString);
  314.                }
  315.             else
  316.                {
  317.                /* Matching KMS area already exists */
  318.  
  319.                CreatePath(apoint);
  320.                printf("-> KMS ->: %s\n", PathString);
  321.                }
  322.  
  323.             free(group2);
  324.             }
  325.  
  326.          free(group);
  327.  
  328.          /* Search a message which has local bit 0 NOT set */
  329.       
  330.          if (!(num = UMSSearchTags(account,UMSTAG_SearchLocal, TRUE,
  331.                                            UMSTAG_SearchMask,  1,
  332.                                            UMSTAG_SearchMatch, 0,
  333.                                            UMSTAG_SearchQuick, TRUE,
  334.                                            TAG_DONE)))
  335.             {
  336.             /* No message found --> leave loop */
  337.       
  338.             break;
  339.             }
  340.  
  341.          /* Get group name */
  342.       
  343.          if (!ReadUMSMsgTags(account,UMSTAG_RMsgNum, num,
  344.                                      UMSTAG_RGroup,  &group,
  345.                                      TAG_DONE)) 
  346.             {
  347.             /* Print error message and quit */
  348.  
  349.             fprintf(stderr, "Error: ReadUMSMsgTags() failed!\n");
  350.             break;
  351.             }
  352.  
  353.          /* Copy group name */
  354.     
  355.          if (!(group = strdup(group)))
  356.             {
  357.             fprintf(stderr, "Error: couldn't copy group name!\n");
  358.             FreeUMSMsg(account, num);
  359.             break;
  360.             }
  361.  
  362.          /* Free UMS message */
  363.          
  364.          FreeUMSMsg(account, num);
  365.          }
  366.       }
  367.    else
  368.       fprintf(stderr, "Error: out of memory!\n");
  369.  
  370.    /* Logout */
  371.    
  372.    UMSLogout(account);
  373.  
  374.    WriteAreaList();
  375.  
  376.    Cleanup();
  377.  
  378.    exit(0);
  379.    }
  380.  
  381. ///
  382.  
  383. /*********************************
  384.  * Cleanup                       *
  385.  *********************************
  386.  * I: ---                        *
  387.  * O: ---                        *
  388.  *********************************/
  389.  
  390. /// Cleanup
  391.  
  392. VOID Cleanup(VOID)
  393.    {
  394.    if (AreaFile)
  395.       free(AreaFile);
  396.    if (KMSRoot)
  397.       free(KMSRoot);
  398.    if (Pattern)
  399.       free(Pattern);
  400.    if (DOSPatt)
  401.       free(DOSPatt);
  402.  
  403.    /* Arealiste freigeben */
  404.  
  405.    struct AreaNode *apoint = AreaList.mlh_Head;
  406.    while(apoint->Node.mln_Succ)
  407.       {
  408.       struct AreaNode *nextapoint = apoint->Node.mln_Succ;
  409.       Remove((struct Node *)apoint);
  410.       FreeMem(apoint, (ULONG)sizeof(struct AreaNode));
  411.       apoint = nextapoint;
  412.       }
  413.    }
  414.  
  415. ///
  416.  
  417. /****************************
  418.  * Parse Arguments          *
  419.  ****************************
  420.  * I: ---                   *
  421.  * O: Error: FALSE Ok: TRUE *
  422.  ****************************/
  423.  
  424. /// ParseArgs
  425.  
  426. #define TEMPLATE "FILENAME/A,ROOT/K,PATTERN/K,FORCE/S"
  427.  
  428. STRPTR HelpTxt = "UMS2KMS 1.0 -*- UMS to KMS Area Converter -*- (c)1994 Thomas Schwarz\n\n" \
  429.                  "This tool creates a KMS area data file containing an area tree based\n" \
  430.                  "on the existing groups in your UMS message base. The tree is built\n" \
  431.                  "according to the UMS group name components which are separated by periods.\n" \
  432.                  "For example: For the UMS group \"comp.sys.amiga.misc\" UMS2KMS will create\n" \
  433.                  "the KMS message area \"/COMP/SYS/AMIGA/MISC\".\n\n" \
  434.                  "Usage:\n\n" \
  435.                  "FILENAME/A    Name of KMS area data file to be read/written/created.\n" \
  436.                  "ROOT/K        Name of KMS root area, the new area tree is to be built\n" \
  437.                  "              in. If not already existent, this area will be created.\n" \
  438.                  "              If no root is given, the new areas are created directly on\n" \
  439.                  "              the uppermost area level.\n" \
  440.                  "PATTERN/K     If given, only for the UMS groups matching this AmigaDOS\n" \
  441.                  "              pattern KMS message areas will be created.\n" \
  442.                  "FORCE/S       Normally no new KMS area is created for an UMS group, if there\n" \
  443.                  "              already exists one assigned to it (but e.g. following an alter-\n" \
  444.                  "              native naming scheme). If this switch is given, KMS areas are\n" \
  445.                  "              created for all UMS groups not pondering about existing areas.\n";
  446.  
  447. BOOL ParseArgs(VOID)
  448.    {
  449.    UBYTE n;
  450.    ULONG args[4];
  451.    BOOL error = FALSE;
  452.    struct RDArgs *rargs = NULL;
  453.    struct RDArgs *myrdargs = NULL;
  454.  
  455.    for(n = 0; n < 4; n++)
  456.       args[n] = 0;
  457.  
  458.    AreaFile = NULL;
  459.    KMSRoot = NULL;
  460.    Pattern = NULL;
  461.    Force = FALSE;
  462.  
  463.    myrdargs = AllocDosObjectTags(DOS_RDARGS, TAG_DONE);
  464.    if(!myrdargs)
  465.       {
  466.       PrintFault(IoErr(), NULL);
  467.       return FALSE;
  468.       }
  469.  
  470.    myrdargs->RDA_ExtHelp = HelpTxt;
  471.  
  472.    if(!(rargs = (struct RDArgs *)ReadArgs(TEMPLATE, args, myrdargs)))
  473.       {
  474.       PrintFault(IoErr(), NULL);
  475.       FreeDosObject(DOS_RDARGS, myrdargs);
  476.       return FALSE;
  477.       }
  478.  
  479.    if (args[0]) /* FILENAME/A */
  480.       {
  481.       AreaFile = strdup((STRPTR)args[0]);
  482.       if (!AreaFile)
  483.          {
  484.          fprintf(stderr, "Error: out of memory.\n");
  485.          error = TRUE;
  486.          }
  487.       }
  488.    if (args[1]) /* ROOT/K */
  489.       {
  490.       KMSRoot = strdup((STRPTR)args[1]);
  491.       if (!KMSRoot)
  492.          {
  493.          fprintf(stderr, "Error: out of memory.\n");
  494.          error = TRUE;
  495.          }
  496.       }
  497.    if (args[2]) /* PATTERN/K */
  498.       {
  499.       Pattern = strdup((STRPTR)args[2]);
  500.       if (!Pattern)
  501.          {
  502.          fprintf(stderr, "Error: out of memory.\n");
  503.          error = TRUE;
  504.          }
  505.       }
  506.    if (args[3]) /* FORCE/S */
  507.       Force = TRUE;
  508.  
  509.    FreeArgs(rargs);
  510.    FreeDosObject(DOS_RDARGS, myrdargs);
  511.  
  512.    if (error)
  513.       return FALSE;
  514.  
  515.    return TRUE;
  516.    }
  517.  
  518. ///
  519.  
  520. /*********************************
  521.  * Areadatei lesen               *
  522.  *********************************
  523.  * I: ---                        *
  524.  * O: Erfolg TRUE/FALSE          *
  525.  *********************************/
  526.  
  527. /// "ReadAreaList"
  528.  
  529. BOOL ReadAreaList(VOID)
  530.    {
  531.    struct AreaNode *apoint;
  532.    struct Area area;
  533.    TEXT buff[LEN_MBNAME+2]; /* MBNAME ist laengstes Element */
  534.    FILE *file;
  535.  
  536.    if (!(file = fopen(AreaFile, "r")))
  537.       return TRUE;
  538.    else
  539.       {
  540.       while(fgets(buff, LEN_AREANAME+2, file))
  541.          {
  542.          if (strlen(buff))
  543.             buff[strlen(buff)-1] = '\0'; /* Linefeed am Ende entfernen */
  544.  
  545.          if (!(apoint = (struct AreaNode *)AllocMem((ULONG)sizeof(struct AreaNode),MEMF_PUBLIC|MEMF_CLEAR)))
  546.             {
  547.             fprintf(stderr, "Error: couldn't AllocMem(AreaNode)!\n");
  548.  
  549.             fclose(file);
  550.  
  551.             return FALSE;
  552.             }
  553.  
  554.          clrmem(&area, sizeof(struct Area));
  555.  
  556.          strcpy(area.Name, buff);
  557.          if (fgets(buff, LEN_AREAINFO+2, file))
  558.             {
  559.             if (strlen(buff))
  560.                buff[strlen(buff)-1] = '\0'; /* Linefeed am Ende entfernen */
  561.             strcpy(area.Info, buff);
  562.             }
  563.          if (fgets(buff, LEN_MBNAME+2, file))
  564.             {
  565.             if (strlen(buff))
  566.                buff[strlen(buff)-1] = '\0';
  567.             strcpy(area.MBName, buff);
  568.             }
  569.          if (fgets(buff, LEN_FILEAREA+2, file))
  570.             {
  571.             if (strlen(buff))
  572.                buff[strlen(buff)-1] = '\0';
  573.             strcpy(area.FilePath, buff);
  574.             }
  575.          if (fgets(buff, LEN_NUMBER+2, file))
  576.             area.ID = (UWORD)atoi(buff);
  577.          if (fgets(buff, LEN_NUMBER+2, file))
  578.             area.Type = (UBYTE)atoi(buff);
  579.          if (fgets(buff, LEN_NUMBER+2, file))
  580.             area.ReadLevel = (UBYTE)atoi(buff);
  581.          if (fgets(buff, LEN_NUMBER+2, file))
  582.             area.WriteLevel = (UBYTE)atoi(buff);
  583.          if (fgets(buff, LEN_NUMBER+2, file))
  584.             area.EditLevel = (UBYTE)atoi(buff);
  585.          if (fgets(buff, LEN_NUMBER+2, file))
  586.             area.AccessBits = (ULONG)atol(buff);
  587.          if (fgets(buff, LEN_NUMBER+2, file))
  588.             area.WriteFlag = (UWORD)atol(buff);
  589.          if (fgets(buff, LEN_NUMBER+2, file))
  590.             area.QuoteStr = (UBYTE)atoi(buff);
  591.          if (fgets(buff, LEN_NUMBER+2, file))
  592.             area.PQuoteStr = (UBYTE)atoi(buff);
  593.          if (fgets(buff, LEN_NUMBER+2, file))
  594.             area.ResendStr = (UBYTE)atoi(buff);
  595.          if (fgets(buff, LEN_NUMBER+2, file))
  596.             area.ForwardStr = (UBYTE)atoi(buff);
  597.          if (fgets(buff, LEN_NUMBER+2, file))
  598.             area.OriginStr = (UBYTE)atoi(buff);
  599.          if (fgets(buff, LEN_NUMBER+2, file))
  600.             area.HoldNum = (UWORD)atoi(buff);
  601.          if (fgets(buff, LEN_NUMBER+2, file))
  602.             area.HoldDays = (UWORD)atoi(buff);
  603.          if (fgets(buff, LEN_NUMBER+2, file))
  604.             area.Mother = (UWORD)atoi(buff);
  605.          if (fgets(buff, LEN_NUMBER+2, file))
  606.             area.Daughter = (UWORD)atoi(buff);
  607.          if (fgets(buff, LEN_NUMBER+2, file))
  608.             area.Next = (UWORD)atoi(buff);
  609.  
  610.          apoint->AreaData = area;
  611.  
  612.          AddTail((struct List *)&AreaList, (struct Node *)apoint);
  613.          }
  614.  
  615.       fclose(file);
  616.       }
  617.  
  618.    return TRUE;
  619.    }
  620.  
  621. ///
  622.  
  623. /*********************************
  624.  * Areadatei schreiben           *
  625.  *********************************
  626.  * I: ---                        *
  627.  * O: Erfolg TRUE/FALSE          *
  628.  *********************************/
  629.  
  630. /// "WriteAreaList"
  631.  
  632. BOOL WriteAreaList(VOID)
  633.    {
  634.    struct AreaNode *apoint;
  635.    FILE *file;
  636.  
  637.    file = fopen(AreaFile, "w");
  638.    if (!file)
  639.       {
  640.       fprintf(stderr, "Error: couldn't write to %s!\n", AreaFile);
  641.       return FALSE;
  642.       }
  643.  
  644.    apoint = (struct AreaNode *)AreaList.mlh_Head;
  645.    while(apoint->Node.mln_Succ)
  646.       {
  647.       fprintf(file,"%s\n%s\n%s\n%s\n",     apoint->AreaData.Name,
  648.                                            apoint->AreaData.Info,
  649.                                            apoint->AreaData.MBName,
  650.                                            apoint->AreaData.FilePath);
  651.       fprintf(file,"%d\n%d\n%d\n%d\n%d\n", apoint->AreaData.ID,
  652.                                            apoint->AreaData.Type,
  653.                                            apoint->AreaData.ReadLevel,
  654.                                            apoint->AreaData.WriteLevel,
  655.                                            apoint->AreaData.EditLevel);
  656.       fprintf(file,"%ld\n%d\n",            apoint->AreaData.AccessBits,
  657.                                            apoint->AreaData.WriteFlag);
  658.       fprintf(file,"%d\n%d\n%d\n%d\n%d\n", apoint->AreaData.QuoteStr,
  659.                                            apoint->AreaData.PQuoteStr,
  660.                                            apoint->AreaData.ResendStr,
  661.                                            apoint->AreaData.ForwardStr,
  662.                                            apoint->AreaData.OriginStr);
  663.       fprintf(file,"%d\n",                 apoint->AreaData.HoldNum);
  664.       fprintf(file,"%d\n",                 apoint->AreaData.HoldDays);
  665.       fprintf(file,"%d\n%d\n%d\n",         apoint->AreaData.Mother,
  666.                                            apoint->AreaData.Daughter,
  667.                                            apoint->AreaData.Next);
  668.  
  669.       apoint = apoint->Node.mln_Succ;
  670.       }
  671.  
  672.    fclose(file);
  673.  
  674.    return TRUE;
  675.    }
  676.  
  677. ///
  678.  
  679. /*******************************************
  680.  * UMS-MsgBase-Namen global suchen         *
  681.  *******************************************
  682.  * I: gesuchte Area                        *
  683.  * O: AreaNode                             *
  684.  *******************************************/
  685.  
  686. /// "GroupSearch"
  687.  
  688. struct AreaNode *GroupSearch(STRPTR name)
  689.    {
  690.    struct AreaNode *apoint;
  691.  
  692.    apoint = (struct AreaNode *)AreaList.mlh_Head;
  693.    while(apoint->Node.mln_Succ)
  694.       {
  695.       if (!stricmp(name, apoint->AreaData.MBName))
  696.          return apoint;
  697.  
  698.       apoint = apoint->Node.mln_Succ;
  699.       }
  700.  
  701.    return NULL;
  702.    }
  703.  
  704. ///
  705.  
  706. /*******************************************
  707.  * KMS-Area auf erster Ebene suchen        *
  708.  *******************************************
  709.  * I: gesuchte Area                        *
  710.  * O: AreaNode                             *
  711.  *******************************************/
  712.  
  713. /// AreaSearch
  714.  
  715. struct AreaNode *AreaSearch(STRPTR name)
  716.    {
  717.    struct AreaNode *apoint;
  718.  
  719.    apoint = SetArea(1);
  720.    if (!apoint)
  721.       return NULL;
  722.  
  723.    apoint = SetArea(apoint->AreaData.Daughter);
  724.  
  725.    while (apoint)
  726.       {
  727.       if (!stricmp(apoint->AreaData.Name, name))
  728.          return apoint;
  729.  
  730.       apoint = SetArea(apoint->AreaData.Next);
  731.       }
  732.  
  733.    return NULL;
  734.    }
  735.  
  736. ///
  737.  
  738. /***************************************
  739.  *  Pfad-String konstruieren           *
  740.  ***************************************
  741.  * I: struct AreaNode *                *
  742.  * O: ---                              *
  743.  ***************************************/
  744.  
  745. /// "CreatePath"
  746.  
  747. VOID CreatePath(struct AreaNode *area)
  748.    {
  749.    struct AreaNode *apoint;
  750.    TEXT merk[LEN_KMSPATH+1];
  751.  
  752.    if (!area)
  753.       {
  754.       *PathString = '\0';
  755.       return;
  756.       }
  757.  
  758.    /* Pfad-String konstruieren */
  759.  
  760.    strcpy(PathString, area->AreaData.Name);
  761.  
  762.    apoint = area;
  763.    while(apoint && apoint->AreaData.Mother && strlen(PathString) < LEN_KMSPATH)
  764.       {
  765.       apoint = SetArea(apoint->AreaData.Mother);
  766.       strcpy(merk, PathString);
  767.       if (apoint && apoint->AreaData.Mother)
  768.          strcpy(PathString, apoint->AreaData.Name);
  769.       else
  770.          strcpy(PathString, "");
  771.       strcat(PathString, "/");
  772.       strncat(PathString, merk, LEN_KMSPATH - strlen(merk));
  773.       PathString[LEN_KMSPATH] = '\0';
  774.       }
  775.    }
  776.  
  777. ///
  778.  
  779. /********************************
  780.  * Area in Liste suchen         *
  781.  ********************************
  782.  * I: Area-Index                *
  783.  * O: struct AreaNode *         *
  784.  ********************************/
  785.  
  786. /// "SetArea"
  787.  
  788. struct AreaNode *SetArea(UWORD idx)
  789.    {
  790.    struct AreaNode *apoint;
  791.  
  792.    if (!idx)
  793.       return NULL;
  794.  
  795.    apoint = (struct AreaNode *)AreaList.mlh_Head;
  796.    if (apoint->Node.mln_Succ)
  797.       {
  798.       while(apoint->Node.mln_Succ && apoint->AreaData.ID != idx)
  799.          apoint = (struct AreaNode *)apoint->Node.mln_Succ;
  800.  
  801.       if (apoint->Node.mln_Succ)
  802.          return apoint;
  803.       else
  804.          return NULL;
  805.       }
  806.    else
  807.       return NULL;
  808.    }
  809.  
  810. ///
  811.  
  812. /********************************
  813.  * Neue Areastruktur einrichten *
  814.  ********************************
  815.  * I: ---                       *
  816.  * O: struct AreaNode *         *
  817.  ********************************/
  818.  
  819. /// InsertArea
  820.  
  821. struct AreaNode *InsertArea(VOID)
  822.    {
  823.    struct AreaNode *apoint, *newapoint;
  824.    UWORD id = 0, previd = 0;
  825.  
  826.    apoint = (struct AreaNode *)AreaList.mlh_TailPred;
  827.    if (!apoint->Node.mln_Pred)
  828.       {
  829.       /* Sonderfall: Erster Listeneintrag */
  830.  
  831.       if (!(newapoint = (struct AreaNode *)AllocMem((ULONG)sizeof(struct AreaNode),MEMF_PUBLIC|MEMF_CLEAR)))
  832.          return NULL;
  833.  
  834.       newapoint->AreaData.ID = 1;
  835.  
  836.       AddTail((struct List *)&AreaList, (struct Node *)newapoint);
  837.  
  838.       return newapoint;
  839.       }
  840.  
  841.    /* Größte ID suchen */
  842.  
  843.    apoint = (struct AreaNode *)AreaList.mlh_Head;
  844.    while(apoint->Node.mln_Succ)
  845.       {
  846.       if (apoint->AreaData.ID > previd)
  847.          previd = apoint->AreaData.ID;
  848.  
  849.       apoint = apoint->Node.mln_Succ;
  850.       }
  851.  
  852.    if (previd + 1 == 0) /* ID-Überlauf */
  853.       {
  854.       previd = 0; id = 0;
  855.       apoint = (struct AreaNode *)AreaList.mlh_Head;
  856.       id = apoint->AreaData.ID;
  857.  
  858.       while(apoint->Node.mln_Succ && previd + 1 == id)
  859.          {
  860.          previd = id;
  861.  
  862.          apoint = (struct AreaNode *)apoint->Node.mln_Succ;
  863.          if (apoint->Node.mln_Succ)
  864.             id = apoint->AreaData.ID;
  865.          }
  866.       }
  867.  
  868.    if (previd == id)
  869.       return NULL;
  870.  
  871.    if (!(newapoint = (struct AreaNode *)AllocMem((ULONG)sizeof(struct AreaNode),MEMF_PUBLIC|MEMF_CLEAR)))
  872.       return NULL;
  873.  
  874.    newapoint->AreaData.ID = previd + 1;
  875.  
  876.    Insert((struct List *)&AreaList, (struct Node *)newapoint, (struct Node *)apoint->Node.mln_Pred);
  877.  
  878.    return newapoint;
  879.    }
  880.  
  881. ///
  882.  
  883. /********************************
  884.  * String -> Großbuchstaben     *
  885.  ********************************
  886.  * I: STRPTR                    *
  887.  * O: ---                       *
  888.  ********************************/
  889.  
  890. /// Upper
  891.  
  892. VOID Upper(STRPTR string)
  893.    {
  894.    if(!string)
  895.       return;
  896.  
  897.    while(*string)
  898.       {
  899.       *string = toupper(*string);
  900.       string++;
  901.       }
  902.    }
  903.  
  904. ///
  905.  
  906. /********************************
  907.  * String -> Kleinbuchstaben    *
  908.  ********************************
  909.  * I: STRPTR                    *
  910.  * O: ---                       *
  911.  ********************************/
  912.  
  913. /// Lower
  914.  
  915. VOID Lower(STRPTR string)
  916.    {
  917.    if(!string)
  918.       return;
  919.  
  920.    while(*string)
  921.       {
  922.       *string = tolower(*string);
  923.       string++;
  924.       }
  925.    }
  926.  
  927. ///
  928.  
  929. /********************************
  930.  * Leerzeichen -> "-"           *
  931.  ********************************
  932.  * I: STRPTR                    *
  933.  * O: ---                       *
  934.  ********************************/
  935.  
  936. /// ConvertSpaces
  937.  
  938. VOID ConvertSpaces(STRPTR string)
  939.    {
  940.    if(!string)
  941.       return;
  942.  
  943.    while(*string)
  944.       {
  945.       if (*string == ' ')
  946.          *string = '-';
  947.       string++;
  948.       }
  949.    }
  950.  
  951. ///
  952.  
  953. /********************************
  954.  * Neue Area einhängen          *
  955.  ********************************
  956.  * I: AreaNode *mother, *new    *
  957.  * O: ---                       *
  958.  ********************************/
  959.  
  960. /// LinkArea
  961.  
  962. VOID LinkArea(struct AreaNode *mother, struct AreaNode *newan)
  963.    {
  964.    if(!mother->AreaData.Daughter)
  965.       {
  966.       /* Neue erste Tochter */
  967.  
  968.       mother->AreaData.Daughter = newan->AreaData.ID;
  969.  
  970.       newan->AreaData.Mother = mother->AreaData.ID;
  971.       newan->AreaData.Next = 0;
  972.       }
  973.    else
  974.       {
  975.       /* Weitere Tochter einsortieren */
  976.  
  977.       struct AreaNode *daughter, *predaughter;
  978.       daughter = SetArea(mother->AreaData.Daughter);
  979.       predaughter = NULL;
  980.  
  981.       /* Alphabetisch einsortieren */
  982.  
  983.       while(daughter && stricmp(newan->AreaData.Name, daughter->AreaData.Name) != -1)
  984.          {
  985.          predaughter = daughter;
  986.          if(daughter->AreaData.Next)
  987.             daughter = SetArea(daughter->AreaData.Next);
  988.          else
  989.             daughter = NULL;
  990.          }
  991.  
  992.       newan->AreaData.Mother = mother->AreaData.ID;
  993.  
  994.       if(!predaughter)
  995.          {
  996.          /* Neue Area ist die erste */
  997.  
  998.          newan->AreaData.Next = daughter->AreaData.ID;
  999.          mother->AreaData.Daughter = newan->AreaData.ID;
  1000.          }
  1001.       else if(!daughter)
  1002.          {
  1003.          /* Neue Area ist die letzte */
  1004.  
  1005.          predaughter->AreaData.Next = newan->AreaData.ID;
  1006.          newan->AreaData.Next = 0;
  1007.          }
  1008.       else
  1009.          {
  1010.          /* Neue Area zwischen predaughter und daughter einhängen */
  1011.  
  1012.          predaughter->AreaData.Next = newan->AreaData.ID;
  1013.          newan->AreaData.Next = daughter->AreaData.ID;
  1014.          }
  1015.       }
  1016.    }
  1017.  
  1018. ///
  1019.  
  1020.